home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
mail
/
mh
/
vmail
/
vmail.2of3
/
init.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-05
|
11KB
|
471 lines
#ifndef lint
static char *RCS_init_c = "$Id: init.c,v 1.3 90/04/23 14:41:11 rogers Exp $";
#endif
/* --------------------
vmail -- init.c
Initialisation routines - setting ttystate, finding valid folders,
trapping signals.
Ttystate is controlled by a mix of curses and ioctl. For simplicity,
initial setups are done with curses. Curses is also used for basic
screen manipulation. However, for speed ioctl is used in switching
in and out of normal terminal state.
Copyright (C) J. Zobel, University of Melbourne, October 1987.
-------------------- */
#include "defs.h"
#include <signal.h>
static struct sgttyb tty, t_tty; /* for holding tty state */
static struct tchars chrs, t_chrs;
static struct ltchars lchrs, t_lchrs;
static char termcap[1024], /* termcap entry */
*cur_folder; /* initial current folder */
sig_type tstp(), tint();
/* --------------------
Start-up routine - set terminal control, signals, etc.
-------------------- */
void
init(argc, argv)
int argc;
char **argv;
{
folder ftmp, find_mail();
char *pargv[20], /* argv from profile */
*profile = (char *) NULL, /* location of MH profile */
*home = (char *) NULL, /* home directory */
*term = (char *) NULL; /* terminal type */
int pargc = 0; /* argc from profile */
get_home(&home);
get_env(&term, &profile, home);
(void)tgetent(termcap, term);
cols = tgetnum("co");
/* lines holds no. of lines for headers, ie "li" less STATUS, TITLE */
lines = tgetnum("li") - 2;
(void)ioctl(0, TIOCGETP, (caddr_t)&tty);
(void)ioctl(0, TIOCGETP, (caddr_t)&chrs);
(void)ioctl(0, TIOCGETP, (caddr_t)&lchrs);
read_profile(&pargc, pargv, profile, home);
process_args(pargc, pargv);
find_folders();
mark_valid_folders(pargc, pargv);
/* give precedence to command line args => process second */
mark_valid_folders(argc, argv);
for(ftmp=folders ; ftmp != (folder) NULL ;)
if(ftmp->valid)
ftmp = find_mail(ftmp, true);
else
ftmp = ftmp->next;
if(curflr->valid == EMPTY) {
(void)printf("%s: folder empty.\n", curflr->name);
exit(1);
}
/* find last instance of initial folder */
LAST_OF_NAME(curflr);
curmail = curflr->mail;
(void)initscr();
(void)crmode();
(void)noecho();
(void)nonl();
(void)signal(SIGTSTP, tstp);
(void)signal(SIGINT, tint);
(void)ioctl(0, TIOCGETP, (caddr_t)&t_tty);
(void)ioctl(0, TIOCGETP, (caddr_t)&t_chrs);
(void)ioctl(0, TIOCGETP, (caddr_t)&t_lchrs);
y = FIRST;
display_page();
}
/* --------------------
Find user name, home directory.
-------------------- */
void
get_home(home)
char **home;
{
struct passwd *pwent, *getpwuid();
#ifdef vax
uid_t getuid();
#endif
pwent = getpwuid((int)getuid());
*home = NEWSTR(strlen(pwent->pw_dir)+1);
(void)strcpy(*home, pwent->pw_dir);
if(access(*home, R_OK | W_OK | X_OK)) {
(void)printf("%s: no permissions.\n", *home);
exit(1);
}
user = NEWSTR(strlen(pwent->pw_name)+1);
(void)strcpy(user, pwent->pw_name);
}
/* --------------------
Find pager, editor, shell, terminal type, MH profile - defaults are PAGER,
EDITOR, SHELL, none, PROFILE. Set by PAGER, EDITOR, SHELL, TERM, MH
environment variables.
-------------------- */
void
get_env(term, profile, home)
char **term, **profile, *home;
{
char **tmp;
for(tmp = environ ; *tmp != (char *) NULL ; tmp++)
if(!strncmp("PAGER=", *tmp, 6)) {
pager = NEWSTR(strlen(*tmp)-4);
(void)strcpy(pager, *tmp+6);
} else if(!strncmp("EDITOR=", *tmp, 7)) {
editor = NEWSTR(strlen(*tmp)-5);
(void)strcpy(editor, *tmp+7);
} else if(!strncmp("SHELL=", *tmp, 6)) {
shell = NEWSTR(strlen(*tmp)-4);
(void)strcpy(shell, *tmp+6);
} else if(!strncmp("TERM=", *tmp, 5)) {
*term = NEWSTR(strlen(*tmp)-3);
(void)strcpy(*term, *tmp+5);
} else if(!strncmp("MH=", *tmp, 3)) {
*profile = NEWSTR(strlen(*tmp)-1);
(void)strcpy(*profile, *tmp+3);
}
if(*term == (char *) NULL) {
(void)printf("Terminal type unknown\n");
exit(1);
}
if(*profile == (char *) NULL) {
*profile = NEWSTR(strlen(home)+strlen(PROFILE)+2);
(void)sprintf(*profile, "%s/%s", home, PROFILE);
}
if(pager == (char *) NULL) {
pager = NEWSTR(strlen(PAGER)+1);
(void)strcpy(pager, PAGER);
}
if(shell == (char *) NULL) {
shell = NEWSTR(strlen(SHELL)+1);
(void)strcpy(shell, SHELL);
}
if(editor == (char *) NULL) {
editor = NEWSTR(strlen(EDITOR)+1);
(void)strcpy(editor, EDITOR);
}
}
static char argkeep[LEN]; /* storage for args from profile */
/* --------------------
Find mail directory, current-folder, context, default options.
-------------------- */
void
read_profile(pargc, pargv, profile, home)
int *pargc;
char **pargv, *profile, *home;
{
FILE *fp, *fopen();
char str[LEN], *ptr, iscontext[LEN], *index(), *next_token();
if((fp = fopen(profile, "r")) == (FILE *) NULL) {
(void)printf("Profile: %s: cannot open.\n", profile);
exit(1);
}
*iscontext = '\0';
while(fgets(str, LEN, fp) != (char *) NULL) {
/* get entries from profile */
if(lstrncmp("context:", str, 8) == 0 && *(ptr=str+8) != '\0') {
squash(str);
(void)strcpy(iscontext, str+8);
} else if(lstrncmp("vmail:", str, 6) == 0 && *(ptr=str+6) != '\0') {
for( ; *ptr == ' ' || *ptr == '\t' ; ptr++)
;
*index(ptr, '\n') = '\0';
(void)strcpy(argkeep, ptr);
for(ptr=argkeep ; *ptr != '\0' ; ) {
pargv[(*pargc)++] = ptr;
ptr = next_token(ptr);
}
} else if(lstrncmp("path:", str, 5) == 0 && *(ptr=str+5) != '\0') {
squash(str);
if(*ptr == '/') { /* full pathname */
mail_dir = NEWSTR(strlen(ptr)+1);
(void)strcpy(mail_dir, ptr);
} else {
mail_dir = NEWSTR(strlen(home)+strlen(ptr)+1);
(void)sprintf(mail_dir, "%s/%s", home, ptr);
}
} else if(lstrncmp("folder-protect:", str, 15) == 0 &&
*(str+15) != '\0') {
squash(str);
folder_protect = atoo(str+15);
} else if(lstrncmp("current-folder:", str, 15) == 0 &&
*(str+15) != '\0') {
squash(str);
cur_folder = NEWSTR(strlen(str+15)+1);
(void)strcpy(cur_folder, str);
}
}
(void)fclose(fp);
if(mail_dir == (char *) NULL) {
mail_dir = NEWSTR(strlen(home)+strlen(MAILDIR)+2);
(void)sprintf(mail_dir, "%s/%s", home, str+6);
}
if(access(mail_dir, R_OK | W_OK | X_OK)) {
(void)printf("%s: no permissions.\n", mail_dir);
exit(1);
}
if(*iscontext == '\0')
(void)strcpy(iscontext, CONTEXT);
context = NEWSTR(strlen(mail_dir)+strlen(iscontext)+2);
(void)sprintf(context, "%s/%s", mail_dir, iscontext);
if(access(context, R_OK | W_OK)) {
(void)printf("%s: no permissions.\n", context);
exit(1);
}
if(cur_folder == (char *) NULL)
cur_folder = CURFOL;
}
/* --------------------
Squash spaces, tabs, newlines out of given string.
-------------------- */
void
squash(str)
char *str;
{
int i, j;
for(i=0, j=0 ; (str[j] = str[i]) != '\0' ; i++)
if(str[j] != ' ' && str[j] != '\t' && str[j] != '\n')
j++;
}
/* --------------------
Mark folders as specified by setenv, command line. At startup, default
is for only active folder to be cur_folder.
-------------------- */
void
mark_valid_folders(argc, argv)
int argc;
char **argv;
{
char *name;
folder f;
name = cur_folder;
/* find valid folders - mark all folders from argv as valid */
for(; argc > 0 ; argc--, argv++)
if(**argv == '+') /* startup folder */
name = (*argv) + 1;
else if(**argv != '-') { /* not a flag */
GOTO_NAME(f, *argv);
if(f == (folder) NULL)
(void)printf("Warning: no such folder as %s\n", *argv);
else
f->valid = true;
}
GOTO_NAME(f, name);
if(f == (folder) NULL) {
(void)printf("%s does not exist\n", name);
exit(1);
}
f->valid = true;
curflr = f;
}
/* --------------------
Reset terminal, clean up.
-------------------- */
void
to_normal()
{
move(lines+FIRST-1, 0);
refresh();
no_control();
(void)printf("\n");
}
/* --------------------
Reset terminal.
-------------------- */
void
no_control()
{
int x, y;
char c;
#ifdef STANDOUT_CLEANUP
/*
* The following code forces curses to issue a standend if it has
* one pending.
*/
getyx(stdscr, y, x);
c = inch() & 0x7f;
if (c == 'a') {
addch('b');
}
else {
addch('a');
}
move(y, x);
refresh();
move(y, x);
addch(c);
move(y, x);
refresh();
#endif
(void)ioctl(0, TIOCSETP, (caddr_t)&tty);
(void)ioctl(0, TIOCSETP, (caddr_t)&chrs);
(void)ioctl(0, TIOCSETP, (caddr_t)&lchrs);
}
/* --------------------
Set terminal.
-------------------- */
void
to_control()
{
(void)ioctl(0, TIOCSETP, (caddr_t)&t_tty);
(void)ioctl(0, TIOCSETP, (caddr_t)&t_chrs);
(void)ioctl(0, TIOCSETP, (caddr_t)&t_lchrs);
}
#define mask(s) (1 << ((s)-1))
/* --------------------
Trap for ^Z.
-------------------- */
sig_type
tstp()
{
int x, y;
getyx(curscr, y, x);
to_normal();
fix_mh();
(void)signal(SIGTSTP, SIG_DFL);
(void)sigsetmask(sigblock(0) &~ mask(SIGTSTP));
(void)kill(0, SIGTSTP);
(void)sigblock(mask(SIGTSTP));
(void)signal(SIGTSTP, tstp);
if(top_level) {
to_control();
touchwin(curscr);
(void)wmove(curscr, y, x);
(void)wrefresh(curscr);
}
}
/* --------------------
Trap for ^?.
-------------------- */
sig_type
tint()
{
touchwin(stdscr);
addstatus("-- interrupt --", true);
longjmp(env, 0); /* jump to main */
}
/* --------------------
Convert an ascii string to octal.
-------------------- */
int
atoo(str)
char *str;
{
int i;
for(; *str < '0' && *str > '7' ; str++)
;
for(i=0 ; *str >= '0' && *str <= '7' ; str++)
i = i*8 + *str - '0';
return(i);
}
/* --------------------
Update MH environment - context and current mail item of current folder.
-------------------- */
fix_mh()
{
char str[LEN], buf[20];
update(context, "Current-Folder:", curflr->name, 15);
(void)sprintf(str, "%s/%s/%s", mail_dir, curflr->name, SEQU);
(void)sprintf(buf, "%d", curmail->number);
update(str, "cur:", buf, 4);
}
/* --------------------
Update file, replacing line beginning with match of len by "match new".
-------------------- */
update(file, match, new, len)
char *file, *match, *new;
int len;
{
FILE *fp, *tmp, *fopen();
bool change = false;
char *mktemp(), *fgets();
char str[LEN], *name = mktemp("/tmp/vmail.XXXXXX");
if((fp = fopen(file, "r")) == (FILE *) NULL) {
if((fp = fopen(file, "w+")) == (FILE *) NULL)
(void)printf("Can't open %s for writing\n", file);
else {
(void)fprintf(fp, "%s %s\n", match, new);
(void)fclose(fp);
}
} else {
if((tmp = fopen(name, "w+")) == (FILE *) NULL)
(void)printf("Can't open %s\n", file);
else {
while(fgets(str, LEN, fp) != (char *) NULL)
if(lstrncmp(str, match, len) == 0) {
change = true;
(void)fprintf(tmp, "%s %s\n", match, new);
} else
(void)fprintf(tmp, "%s", str);
if(! change)
(void)fprintf(tmp, "%s %s\n", match, new);
(void)fclose(fp);
(void)fclose(tmp);
if((fp = fopen(file, "w+")) == (FILE *) NULL)
(void)printf("Can't open %s for writing\n", file);
else {
tmp = fopen(name, "r");
while(fgets(str, LEN, tmp) != (char *) NULL)
(void)fprintf(fp, "%s", str);
(void)fclose(fp);
(void)fclose(tmp);
(void)unlink(name);
}
}
}
}